/*
    Project:        Home Power Control
    File:           HPCSensors.cpp
    Author:         christian@karunamusic.at
    Date:           02.2015
    Description:    Sensors for the server.
                    Actually they do nothing - get its value from the clients over a tcp-socket.
 */

#include <Logger/HPCLogger.h>
#include "HPCSensors.h"

unsigned int HPCAnemometer::Beaufort()
{
    int ret;
    float fl = m_Value.V().toFloat();
    if ( fl <= 2.0 )
    {
        ret = 0;
    }
    else if ( fl >  2.0 && fl <=  5.0 )
    {
        ret = 1;
    }
    else if ( fl >  5.0 && fl <= 11.0 )
    {
        ret = 2;
    }
    else if ( fl > 11.0 && fl <= 19.0 )
    {
        ret = 3;
    }
    else if ( fl > 19.0 && fl <= 28.0 )
    {
        ret = 4;
    }
    else if ( fl > 28.0 && fl <= 38.0 )
    {
        ret = 5;
    }
    else if ( fl > 38.0 && fl <= 49.0 )
    {
        ret = 6;
    }
    else if ( fl > 49.0 && fl <= 61.0 )
    {
        ret = 7;
    }
    else if ( fl > 61.0 && fl <= 74.0 )
    {
        ret = 8;
    }
    else if ( fl > 74.0 && fl <= 89.0 )
    {
        ret = 9;
    }
    else if ( fl > 89.0 && fl <= 102.0 )
    {
        ret = 10;
    }
    else if ( fl > 102.0 && fl <= 117.0 )
    {
        ret = 11;
    }
    else
    {
        ret = 12;
    }

    return ret;
}

QString HPCAnemometer::asString() const
{
    QString ret = HPCSensor::asString();

    ret += ", interval " + QString::number(m_Interval);
    return ret;
}

QString HPCRainGauge::asString() const
{
    QString ret = HPCSensor::asString();

    ret += ", interval " + QString::number(m_Interval);
    return ret;
}

QString HPCWindVane::asString() const
{
    QString ret = HPCSensor::asString();

    ret += ", channel " + QString::number(m_Channel);
    return ret;
}

float HPCWindVane::Degrees()
{
    float degs[] = {112.5,67.5,90.0,157.5,135.0,202.5,180.0,22.5,45.0,247.5,225.0,337.5,0.0,292.5,315.0,270.0};
    unsigned int i = m_Value.V().toUInt();
    if ( i >= 1 && i <= 16 )
        return degs[i];

    LOG(error,"Cannot get degrees - invalid value from WindVane!");
    return -1.0;
}

QString HPCWindVane::dirString()
{
    QStringList wtxt = {"N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"};
    unsigned int i = m_Value.V().toUInt();
    if ( i >= 1 && i <= 16 )
        return wtxt[i];

    LOG(error,"Cannot get dirstring - invalid value from WindVane!");
    return "";
}

const double HPCBarometer::SEA_LEVEL_PRESSURE = 101.325;
const double HPCBarometer::ALT_EXP = 1.0 / 5.255;

int HPCBarometer::getRelativeAltitude( float pressure )
{
    // This formula is from sec. 3.6 of the data sheet.
    double n = pow(((double)pressure / SEA_LEVEL_PRESSURE), ALT_EXP);
    return (int)(44330.0 * (1.0 - n));
}

float HPCBarometer::getMeanPressure( int height )
{
    double n = pow(1.0 - ((double)height/44330.0), 5.255);
    return (float)(SEA_LEVEL_PRESSURE * n);
}

/* Stream operators */

QDataStream& operator<< ( QDataStream& os, HPCButton& s )
{
    os << static_cast<HPCSensor&>(s);
    return os;
}

QDataStream& operator<< ( QDataStream& os, HPCLight& s )
{
    os << static_cast<HPCSensor&>(s);
    return os;
}

QDataStream& operator<< ( QDataStream& os, HPCAnemometer& s )
{
    os << static_cast<HPCSensor&>(s);
    os << s.Interval();
    return os;
}

QDataStream& operator<< ( QDataStream& os, HPCRainGauge& s )
{
    os << static_cast<HPCSensor&>(s);
    os << s.Interval();
    return os;
}

QDataStream& operator<< ( QDataStream& os, HPCWindVane& s )
{
    os << static_cast<HPCSensor&>(s);
    os << s.Channel();
   return os;
}

QDataStream& operator<< ( QDataStream& os, HPCHumidity22& s )
{
    os << static_cast<HPCSensor&>(s);
    return os;
}

QDataStream& operator<< ( QDataStream& os, HPCTemperature22& s )
{
    os << static_cast<HPCSensor&>(s);
    return os;
}

QDataStream& operator<< ( QDataStream& os, HPCBarometer& s )
{
    os << static_cast<HPCSensor&>(s);
    return os;
}
